package wechat

import (
	"context"

	v1 "caas-platform-payment/api/wechat/v1"
	"caas-platform-payment/internal/consts"
	"caas-platform-payment/internal/dao"
	"caas-platform-payment/internal/model/entity"

	"github.com/gogf/gf/v2/errors/gcode"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/wechatpay-apiv3/wechatpay-go/core"
	"github.com/wechatpay-apiv3/wechatpay-go/core/option"
	"github.com/wechatpay-apiv3/wechatpay-go/services/payments/jsapi"
	"github.com/wechatpay-apiv3/wechatpay-go/utils"
)

func (c *ControllerV1) QueryOrder(ctx context.Context, req *v1.QueryOrderReq) (res *v1.QueryOrderRes, err error) {
	tenantCode := ctx.Value(consts.TokenClaims.TenantCode).(string)
	// 读取商户信息
	cls := dao.PayChannel.Columns()
	if req.AppId == "" {
		l.Error(ctx, req)
		return nil, gerror.NewCode(gcode.CodeInvalidParameter, "参数错误")
	}
	ch := &entity.PayChannel{}
	err = dao.PayChannel.Ctx(ctx).Where(cls.TenantCode, tenantCode).Where(cls.AppId, req.AppId).Where(cls.ChannelName, consts.PayChannels[0].Name).Scan(ch)
	if err != nil || ch.Id == 0 {
		l.Error(ctx, err)
		return nil, gerror.NewCode(consts.MerchantNotFound)
	}
	// 加载私钥
	privateKey, err := utils.LoadPrivateKey(ch.PrivateKey)
	if err != nil {
		l.Error(ctx, err)
		return nil, gerror.NewCode(consts.LoadPrivateKeyFailed)
	}
	opts := []core.ClientOption{
		option.WithWechatPayAutoAuthCipher(ch.MerchantId, ch.MerchantCertSerialNumber, privateKey, ch.MerchantApiKey),
	}
	client, err := core.NewClient(ctx, opts...)
	if err != nil {
		l.Error(ctx, err)
		return nil, gerror.NewCode(consts.WechatClientInitFailed)
	}
	svc := jsapi.JsapiApiService{Client: client}
	// 通过支付订单号查询订单情况
	resp, result, err := svc.QueryOrderByOutTradeNo(ctx, jsapi.QueryOrderByOutTradeNoRequest{
		OutTradeNo: &req.OutTradeNo,
		Mchid:      &ch.MerchantId,
	})
	if err != nil {
		l.Error(ctx, err)
		return nil, gerror.NewCode(consts.WechatPayFailed)
	}
	if result.Response.StatusCode != 200 {
		l.Error(ctx, result.Response)
		return nil, gerror.NewCode(consts.WechatPayFailed)
	}
	return &v1.QueryOrderRes{
		Appid:          resp.Appid,
		Currency:       resp.Amount.Currency,
		TotalFee:       resp.Amount.Total,
		Mchid:          resp.Mchid,
		Openid:         resp.Payer.Openid,
		OutTradeNo:     resp.OutTradeNo,
		TradeState:     resp.TradeState,
		TradeStateDesc: resp.TradeStateDesc,
	}, nil
}
